//package com.example.common.rc.aop.dicttrans;
//
//import cn.hutool.core.bean.BeanUtil;
//import cn.hutool.core.util.ArrayUtil;
//import cn.hutool.core.util.ReflectUtil;
//import com.alibaba.fastjson.JSON;
//import com.alibaba.fastjson.JSONObject;
//import com.baomidou.mybatisplus.core.metadata.IPage;
//import com.example.common.api.CommonAPI;
//import com.example.common.core.CommonConstant;
//import com.example.common.core.Result;
//import com.example.common.rc.aop.dicttrans.ssistutil.JavassistUtil2;
//import com.example.common.sys.model.DictModel;
//import com.example.crud.sys.model.DictModel;
//import lombok.AllArgsConstructor;
//import lombok.Getter;
//import lombok.SneakyThrows;
//import lombok.extern.slf4j.Slf4j;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.annotation.Around;
//import org.aspectj.lang.annotation.Aspect;
//import org.aspectj.lang.annotation.Pointcut;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//
//import java.lang.reflect.Field;
//import java.util.*;
//import java.util.function.BiFunction;
//import java.util.function.Function;
//import java.util.stream.Collectors;
//
///**
// * @Description: 字典aop类
// * @Author: dangzhenghui
// * @Date: 2019-3-17 21:50
// * @Version: 1.0
// */
//@Aspect
//@Component
//@Slf4j
//public class DictAop {
//
//    //@Lazy
//    @Autowired
//    private CommonAPI commonAPI;
//
//    @Pointcut("execution(* com.example..BaseController.*(..))")
//    public void p1() {
//    }
//
//    @Pointcut("execution(* com.example..*Controller.*(..))")
//    public void p2() {
//    }
//
//    @Pointcut("execution(* com.example..*Api.*(..))")
//    public void p3() {
//    }
//
////    @Pointcut("@annotation(org.springframework.web.bind.annotation.ResponseBody) && args(result, ..)")
////    public void pBody() {
////    }
//
//    //@Around("execution(public * org.jeecg.modules..*.*Api.*(..)) && @annotation(needTransLate)")
//
//    @Around("@annotation(com.example.common.rc.aop.dicttrans.dictaop.NeedTransLate)||(p1()||p2()||p3())")
//    @SneakyThrows
//    public Object transLateDict(ProceedingJoinPoint pjp) {
//        Object proceed = pjp.proceed();
//        if (proceed instanceof Result) {
//            Result result = (Result) proceed;
//            Object outVO = result.getResult();
//            Class<?> aClass = outVO.getClass();
//            //包装类型拆一层即为非包装类型,进行模式匹配
//            BiFunction<Object, Function<Object, Object>, ?> consumerByType = PatternMatching.getConsumerByType(aClass);
//            if (Objects.nonNull(consumerByType)) {
//                Object apply = consumerByType.apply(outVO, this::transOutVO);
//                result.setResult(apply);
//                return result;
//            }
//
//            result.setResult(this.transOutVO(outVO));
//            return result;
//        }
//        //走到这就是各种非包装类型的,进行模式匹配
//        BiFunction<Object, Function<Object, Object>, ?> consumerByType = PatternMatching.getConsumerByType(proceed.getClass());
//        if (Objects.nonNull(consumerByType)) {
//            Object apply = consumerByType.apply(proceed, this::transOutVO);
//            return apply;
//        }
//        //走到这就是只返回实体类型的
//        return this.transOutVO(proceed);
//    }
//
//    /**
//     * 实体上带有注解的翻译成中文
//     *
//     * @param obj 记录
//     */
//    @SneakyThrows
//    private Object transOutVO(Object obj) {
//        Class<?> aClass = obj.getClass();
//        Field[] declaredFields = aClass.getDeclaredFields();
//
//        String[] needAddFields = Arrays.stream(declaredFields)
//                .filter(field -> field.isAnnotationPresent(DictCode2Name.class) && Objects.nonNull(ReflectUtil.getFieldValue(obj, field)))
//                .peek(e -> e.setAccessible(true))
//                .map(field1 -> field1.getName() + CommonConstant.DICT_TEXT_SUFFIX)
//                .toArray(String[]::new);
//
//        //没要需要翻译的直接return
//        if (ArrayUtil.isEmpty(needAddFields)) {return obj;}
//
//        //创建增加字段后的子类字节码
//        Class<?> subclass = JavassistUtil2.createSubclass(aClass, needAddFields);
////        Object o = Class.forName(subclass.getName()).newInstance();
//        Object o = subclass.newInstance();
////        boolean equals = o1.equals(o);
//        BeanUtil.copyProperties(obj, o);
//
//        Arrays.stream(declaredFields)
//                .filter(field -> field.isAnnotationPresent(DictCode2Name.class) && Objects.nonNull(ReflectUtil.getFieldValue(obj, field)))
//                .peek(e -> e.setAccessible(true))
//                .forEach(field -> {
//                    field.setAccessible(true);
//                    DictCode2Name annotation = field.getAnnotation(DictCode2Name.class);
//                    String dictCode = Optional.ofNullable(annotation.value()).orElse(annotation.dicCode());
//                    String fieldDictValue = (String) ReflectUtil.getFieldValue(obj, field);
//                    boolean isUseSysDefaultDict = annotation.useSysDefaultDict();
//                    //代理子类的属性名称(加了字典后缀)
//                    String childFieldName = field.getName() + CommonConstant.DICT_TEXT_SUFFIX;
//
//                    //代理子类将要设置的label
//                    String childFieldLabel = "";
//
//                    //如果不是内置字典的翻译
//                    if (!isUseSysDefaultDict) {
//                        String tab = annotation.tab();
//                        String codeColumn = annotation.codeColumn();
//                        String nameColumn = annotation.nameColumn();
//                        if (!annotation.isMulti()) {
//                            childFieldLabel = commonAPI.translateDictFromTable(tab, nameColumn, codeColumn, fieldDictValue);
//                        } else {
//                            //如果是多个用逗号隔开的翻译
//                            Map<String, String> relation = commonAPI.translateDictFromTableByKeys(tab, nameColumn, codeColumn, fieldDictValue).stream().collect(Collectors.toMap(DictModel::getValue, DictModel::getLabel));
//                            String[] split = fieldDictValue.split(",");
//                            childFieldLabel = Arrays.stream(split).map(relation::get).collect(Collectors.joining(","));
//                        }
//
//                    } else {
//
//                        if (!annotation.isMulti()) {
//                            childFieldLabel = commonAPI.translateDict(dictCode, fieldDictValue);
//                        } else {
//
//                            Map<String, List<DictModel>> stringListMap = commonAPI.translateManyDict(dictCode, fieldDictValue);
//                            List<DictModel> dictModels = stringListMap.get(dictCode);
//                            childFieldLabel = dictModels.stream()
//                                    .map(DictModel::getLabel)
//                                    .collect(Collectors.joining(","));
//                        }
//                    }
//                    Field field1 = ReflectUtil.getField(subclass, childFieldName);
//                    ReflectUtil.setFieldValue(o, field1, childFieldLabel);
//
//                });
//        return o;
//    }
//
//    public static void findAnnoMao(String[] args) {
//        String das = "cjaosijcoiasj";
//        String s = JSON.toJSONString(das);
//        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(das));
//        System.out.println(jsonObject);
//    }
//
//    @Getter
//    @AllArgsConstructor
//    @SuppressWarnings({"all"})
//    public enum PatternMatching {
//        IPAGE(IPage.class, (outVO, translater) -> {
//            IPage y = (IPage) outVO;
//            List records = y.getRecords();
//            List<Object> dasd = (List<Object>) records.stream().map(x -> translater.apply(x)).collect(Collectors.toList());
//            y.setRecords(dasd);
//            return y;
//        }),
//
//        LIST(List.class, (outVO, translater) -> {
//            List result = (List) outVO;
//            // result.forEach(x -> translateConsumer.apply(x));
//            List<Object> dasd = (List<Object>) result.stream().map(x -> translater.apply(x)).collect(Collectors.toList());
//            return dasd;
//            // res.setResult(result);
//        }),
//        STRING(String.class, (str, translater) -> {
//            Object apply = translater.apply(str);
//            return apply;
//        });
//
//        private final Class<?> aClass;
//
//        private final BiFunction<Object, Function<Object, Object>, ?> consumer;
//
//        public static BiFunction<Object, Function<Object, Object>, ?> getConsumerByType(Class<?> clazz) {
//            return Arrays.stream(PatternMatching.values()).filter(e -> e.getAClass().isAssignableFrom(clazz))
//                    .map(PatternMatching::getConsumer).findAny().orElse(null);
//        }
//
//    }
//}
